Computing devices perform tasks by executing computer instructions. A set of computing instructions for performing a particular task form a function. A set of functions that interact for performing related tasks form an application. Two or more different applications may need to use the same function to perform the same particular task. While it is possible to include the same function's computing instructions in each of the different applications, it is more efficient for each application to use the same function. By using the same function, less memory is used to store instructions, and modifications to the function need only be made in one place.
To allow more than one application to use the same functions, a library of functions, i.e., a library, is formed. Typically, a function's computer instructions and a reference to the computer instructions is placed in the library. This is done for each of the functions in a library. An application uses a function in a library, i.e., a library function, by calling the function using the reference.
Functions may call other functions in the same library. Functions may also call functions in another library. Hence, it is possible for a library to depend on another library. For example, an application may depend on library A that depends on library B which depends on library C. In order to properly load and initialize the application, libraries A, B, and C must be loaded and initialized in a way that prevents the functions in the libraries from being called before the libraries are properly prepared. If a function in a library is called before the library containing the function is properly prepared, the function and/or the data used by the function may be in an indeterminate state. A function and/or data that is in an indeterminate state can cause, for example, the function to overwrite random memory locations that, in turn, can cause further malfunctions that are often difficult to detect. To ensure that the libraries are properly prepared, it is preferable that in the above example first library C is loaded and initialized, then library B, next library A, and finally the application is loaded and initialized.
Two libraries may have a “dependency relationship” or “dependency” if the first of the two libraries depends on the second library, i.e., if the first library uses functions in the second library. The dependency between the two libraries can be represented in software by a link. The dependencies in a set of libraries, such as the set of libraries described above, can be described by a dependency tree comprising a plurality of links. Using the above-described set of libraries as an example, in a dependency tree describing the libraries, the application has a link to library A which has a link to library B which has a link to library C.
It is also possible for libraries to be co-dependent. For example, if library B depends library C and library C depends on library B, libraries B and C are co-dependent. That is, there are two links between libraries B and C, which creates a cycle. A cycle is produced if, directly or indirectly, a supporting library for another library is also a dependent library. In the case of a cycle, the order in which the libraries are initialized is not clear. A traditional way to resolve the described loading problem is to break the cycle by arbitrarily choosing one of the libraries to load and initialize first.